<template>
  <div class="log-page">
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">系统日志</h1>
        <p class="page-subtitle">查看和管理系统操作日志</p>
      </div>
      <div class="header-actions">
        <el-button type="danger" @click="handleClearLogs">
          <el-icon><Delete /></el-icon>
          清空日志
        </el-button>
        <el-button @click="handleRefresh">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
      </div>
    </div>

    <!-- 搜索和筛选 -->
    <div class="search-section">
      <div class="search-left">
        <el-input
          v-model="searchQuery"
          placeholder="搜索日志..."
          prefix-icon="Search"
          style="width: 300px"
          clearable
        />
        <el-select v-model="levelFilter" placeholder="日志级别" style="width: 150px">
          <el-option label="全部" value="" />
          <el-option label="INFO" value="INFO" />
          <el-option label="WARN" value="WARN" />
          <el-option label="ERROR" value="ERROR" />
          <el-option label="DEBUG" value="DEBUG" />
        </el-select>
        <el-date-picker
          v-model="dateRange"
          type="datetimerange"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          style="width: 350px"
        />
      </div>
      <div class="search-right">
        <el-button-group>
          <el-button :type="viewMode === 'table' ? 'primary' : ''" @click="viewMode = 'table'">
            <el-icon><List /></el-icon>
          </el-button>
          <el-button :type="viewMode === 'timeline' ? 'primary' : ''" @click="viewMode = 'timeline'">
            <el-icon><Grid /></el-icon>
          </el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 日志列表 -->
    <div class="log-content">
      <!-- 表格视图 -->
      <div v-if="viewMode === 'table'" class="table-view">
        <el-table 
          :data="filteredLogs" 
          style="width: 100%" 
          class="log-table"
          v-loading="loading"
        >
          <el-table-column prop="createTime" label="时间" min-width="180" show-overflow-tooltip>
            <template #default="{ row }">
              {{ formatDate(row.createTime) }}
            </template>
          </el-table-column>
          <el-table-column prop="result" label="级别" width="100">
            <template #default="{ row }">
              <el-tag :type="row.result === 1 ? 'success' : 'danger'" size="small">
                {{ row.result === 1 ? '成功' : '失败' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="method" label="方法" min-width="150" show-overflow-tooltip />
          <el-table-column prop="operation" label="操作" min-width="300" show-overflow-tooltip />
          <el-table-column prop="username" label="操作用户" min-width="120" show-overflow-tooltip />
          <el-table-column prop="ip" label="IP地址" min-width="120" show-overflow-tooltip />
          <el-table-column label="操作" width="140" fixed="right">
            <template #default="{ row }">
              <el-button size="small" @click="handleViewDetail(row)">详情</el-button>
              <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 时间线视图 -->
      <div v-else class="timeline-view">
        <div class="log-timeline">
          <el-timeline>
            <el-timeline-item
              v-for="log in filteredLogs"
              :key="log.id"
              :timestamp="log.timestamp"
              :type="getTimelineItemType(log.level)"
              :color="getTimelineItemColor(log.level)"
            >
              <div class="timeline-content">
                <div class="log-header">
                  <el-tag :type="getLogLevelTag(log.level)" size="small">
                    {{ log.level }}
                  </el-tag>
                  <span class="logger-name">{{ log.logger }}</span>
                  <span class="username">{{ log.username }}</span>
                  <span class="ip-address">{{ log.ip }}</span>
                </div>
                <div class="log-message">{{ log.message }}</div>
                <div class="log-actions">
                  <el-button size="small" @click="handleViewDetail(log)">详情</el-button>
                  <el-button size="small" type="danger" @click="handleDelete(log)">删除</el-button>
                </div>
              </div>
            </el-timeline-item>
          </el-timeline>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <div class="pagination-section">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 日志详情对话框 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="日志详情"
      width="800px"
    >
      <div v-if="selectedLog" class="log-detail">
        <div class="detail-item">
          <label>时间：</label>
          <span>{{ selectedLog.timestamp }}</span>
        </div>
        <div class="detail-item">
          <label>级别：</label>
          <el-tag :type="getLogLevelTag(selectedLog.level)" size="small">
            {{ selectedLog.level }}
          </el-tag>
        </div>
        <div class="detail-item">
          <label>日志器：</label>
          <span>{{ selectedLog.logger }}</span>
        </div>
        <div class="detail-item">
          <label>消息：</label>
          <span>{{ selectedLog.message }}</span>
        </div>
        <div class="detail-item">
          <label>操作用户：</label>
          <span>{{ selectedLog.username }}</span>
        </div>
        <div class="detail-item">
          <label>IP地址：</label>
          <span>{{ selectedLog.ip }}</span>
        </div>
        <div class="detail-item" v-if="selectedLog.stackTrace">
          <label>堆栈信息：</label>
          <pre class="stack-trace">{{ selectedLog.stackTrace }}</pre>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Refresh, List, Grid } from '@element-plus/icons-vue'
import { sysLogApi } from '@/api'

// 响应式数据
const loading = ref(false)
const logList = ref([])
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
const searchQuery = ref('')
const levelFilter = ref('')
const dateRange = ref([])
const viewMode = ref('table')
const detailDialogVisible = ref(false)
const selectedLog = ref(null)

// 计算属性
const filteredLogs = computed(() => {
  let filtered = logList.value

  if (searchQuery.value) {
    filtered = filtered.filter(log =>
      log.message.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
      log.logger.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
      (log.username && log.username.toLowerCase().includes(searchQuery.value.toLowerCase()))
    )
  }

  if (levelFilter.value !== '') {
    filtered = filtered.filter(log => log.level === levelFilter.value)
  }

  if (dateRange.value && dateRange.value.length === 2) {
    const startTime = dateRange.value[0].getTime()
    const endTime = dateRange.value[1].getTime()
    filtered = filtered.filter(log => {
      const logTime = new Date(log.timestamp).getTime()
      return logTime >= startTime && logTime <= endTime
    })
  }

  return filtered
})

const loadLogList = async () => {
  loading.value = true
  try {
    const params = {
      current: currentPage.value,
      size: pageSize.value
    }
    
    if (searchQuery.value) {
      params.username = searchQuery.value
      params.operation = searchQuery.value
    }
    
    if (levelFilter.value) {
      // 根据级别过滤，这里需要根据实际后端字段调整
      params.level = levelFilter.value
    }
    
    if (dateRange.value && dateRange.value.length === 2) {
      params.startTime = dateRange.value[0].toISOString()
      params.endTime = dateRange.value[1].toISOString()
    }
    
    const response = await sysLogApi.getLogList(params)
    
    if (response.code === 200) {
      logList.value = response.data.records || []
      total.value = response.data.total || 0
    } else {
      ElMessage.error(response.message || '加载日志列表失败')
    }
  } catch (error) {
    console.error('加载日志列表失败:', error)
    ElMessage.error('加载日志列表失败')
  } finally {
    loading.value = false
  }
}

const handleViewDetail = (log) => {
  selectedLog.value = log
  detailDialogVisible.value = true
}

const handleDelete = async (log) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除这条日志吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const response = await sysLogApi.deleteLog(log.id)
    if (response.code === 200) {
      ElMessage.success('删除成功')
      loadLogList()
    } else {
      ElMessage.error(response.message || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除日志失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

const handleClearLogs = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要清空所有日志吗？此操作不可恢复！',
      '确认清空',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const response = await sysLogApi.clearLogs()
    if (response.code === 200) {
      ElMessage.success('日志清空成功')
      loadLogList()
    } else {
      ElMessage.error(response.message || '清空失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('清空日志失败:', error)
      ElMessage.error('清空失败')
    }
  }
}

const handleRefresh = () => {
  loadLogList()
}

const handleSizeChange = (size) => {
  pageSize.value = size
  currentPage.value = 1
  loadLogList()
}

const handleCurrentChange = (page) => {
  currentPage.value = page
  loadLogList()
}

const getLogLevelTag = (level) => {
  const tagMap = {
    'INFO': 'success',
    'WARN': 'warning',
    'ERROR': 'danger',
    'DEBUG': 'info'
  }
  return tagMap[level] || 'info'
}

const getTimelineItemType = (level) => {
  const typeMap = {
    'INFO': 'success',
    'WARN': 'warning',
    'ERROR': 'danger',
    'DEBUG': 'info'
  }
  return typeMap[level] || 'info'
}

const getTimelineItemColor = (level) => {
  const colorMap = {
    'INFO': '#67C23A',
    'WARN': '#E6A23C',
    'ERROR': '#F56C6C',
    'DEBUG': '#909399'
  }
  return colorMap[level] || '#909399'
}

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '未知时间'
  
  try {
    const date = new Date(dateString)
    if (isNaN(date.getTime())) {
      return '无效时间'
    }
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    })
  } catch (error) {
    console.error('日期格式化错误:', error, dateString)
    return '时间格式错误'
  }
}

onMounted(() => {
  loadLogList()
})
</script>

<style lang="scss" scoped>
.log-page {
  animation: fadeIn 0.6s ease-out;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 32px;
  padding: 24px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 16px;
  box-shadow: var(--shadow-lg);
}

.header-content {
  .page-title {
    font-size: 24px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 8px;
  }
  
  .page-subtitle {
    color: var(--text-secondary);
    font-size: 16px;
  }
}

.header-actions {
  display: flex;
  gap: 12px;
}

.search-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding: 20px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 12px;
}

.search-left {
  display: flex;
  gap: 16px;
}

.log-content {
  margin-bottom: 24px;
}

.table-view {
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  box-shadow: none;
}

.log-table {
  :deep(.el-table) {
    border: none;
    background: transparent;
  }
  
  :deep(.el-table__header) {
    background: transparent;
    
    .el-table__cell {
      background: transparent;
      border: none;
      color: var(--text-secondary);
      font-weight: 500;
      padding: 16px 0;
    }
  }
  
  :deep(.el-table__row) {
    background: transparent;
    border: none;
    
    &:hover {
      background: var(--bg-tertiary);
    }
    
    .el-table__cell {
      border: none;
      padding: 16px 0;
      background: transparent;
    }
  }
  
  :deep(.el-table__inner-wrapper) {
    border: none;
  }
  
  :deep(.el-table__border-line) {
    display: none;
  }
}

.timeline-view {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 20px;
  box-shadow: var(--shadow-lg);
}

.log-timeline {
  :deep(.el-timeline-item__content) {
    background: var(--bg-secondary);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 8px;
  }
}

.timeline-content {
  .log-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
    
    .logger-name {
      font-weight: 500;
      color: var(--text-primary);
    }
    
    .username {
      color: var(--text-secondary);
      font-size: 14px;
    }
    
    .ip-address {
      color: var(--text-muted);
      font-size: 12px;
    }
  }
  
  .log-message {
    color: var(--text-primary);
    margin-bottom: 12px;
    line-height: 1.5;
  }
  
  .log-actions {
    display: flex;
    gap: 8px;
  }
}

.log-detail {
  .detail-item {
    display: flex;
    margin-bottom: 16px;
    
    label {
      font-weight: 500;
      color: var(--text-secondary);
      width: 100px;
      flex-shrink: 0;
    }
    
    span {
      color: var(--text-primary);
      flex: 1;
    }
    
    .stack-trace {
      background: var(--bg-secondary);
      padding: 12px;
      border-radius: 6px;
      font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
      font-size: 12px;
      color: var(--text-primary);
      white-space: pre-wrap;
      max-height: 200px;
      overflow-y: auto;
    }
  }
}

.pagination-section {
  display: flex;
  justify-content: center;
  padding: 20px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
}

// 响应式设计
@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    gap: 20px;
    text-align: center;
  }
  
  .search-section {
    flex-direction: column;
    gap: 16px;
  }
  
  .search-left {
    width: 100%;
    flex-direction: column;
  }
  
  .log-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
}
</style> 